package com.shaozi.nc.hibservice;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.shaozi.data.hib.dao.BaseHibDao;
import com.shaozi.data.hib.service.BaseServiceImpl;
import com.shaozi.lib.throwable.SzException;
import com.shaozi.utils.common.SysUtils;
import com.shaozi.nc.data.hibVO.CrmCustomerVO;
import com.shaozi.nc.quartz.crm.pojo.OpenSeeRulePipelinePojo;
import com.shaozi.nc.quartz.crm.pojo.UserCountPojo;

@Service(value = "crmCustomerService")
public class CrmCustomerService extends BaseServiceImpl<CrmCustomerVO> {

	private Logger logger = Logger.getLogger(CrmCustomerService.class);

	@Autowired
	private CrmOrderService crmOrderService;

	@Autowired
	public CrmCustomerService(BaseHibDao<CrmCustomerVO> baseHibDao) {
		super(baseHibDao);

	}

	/**
	 * 检查是否有未跟进的记录
	 * 
	 * @param companyId
	 * @param id
	 * @param noAcitivityDay
	 * @return
	 * @throws SzException
	 */
	public CrmCustomerVO checkNoActivityBackIdExists(String companyId, int id, int noAcitivityDay) throws SzException {
		String hql = "from CrmCustomerVO where isDelete=0 and lastActiveRecordTime<=UNIX_TIMESTAMP(NOW())*1000 -("
				+ noAcitivityDay + "-1)*86400000 and ";
		hql += "id= " + id
				+ " AND ownerUid != -1 and ownerUid !=0 AND insertTime< UNIX_TIMESTAMP(NOW())*1000 AND companyId="
				+ companyId;
		List<CrmCustomerVO> vos = getDao().getDaoSupport().queryObjects(hql, -1, 1);
		return vos.isEmpty() ? null : vos.get(0);
	}

	public CrmCustomerVO checkNoOrderBackIdExists(String companyId, int id, int noOrderDay) throws SzException {
		String hql = "from CrmCustomerVO where isDelete=0 and insertTime<=UNIX_TIMESTAMP(NOW())*1000 -(" + noOrderDay
				+ "-1)*86400000 and orderTime=0 and ";
		hql += "id= " + id + " AND ownerUid != -1 and ownerUid !=0 AND companyId=" + companyId;
		List<CrmCustomerVO> vos = getDao().getDaoSupport().queryObjects(hql, -1, 1);
		return vos.isEmpty() ? null : vos.get(0);
	}

	// 未跟进退回公海
	public List<UserCountPojo> noActivityBackGroupByUser(String companyId, OpenSeeRulePipelinePojo ruleVo,
			List<Integer> stageIds) throws SzException {
		String hql = getNoActivityBackHsql(companyId, ruleVo, stageIds);
		List counts = getDao().getDaoSupport().queryObjects(hql, -1, -1);
		return classifyUserCount(counts);
	}

	// 未跟进退回公海
	public List<CrmCustomerVO> noActivityBack(String companyId, OpenSeeRulePipelinePojo ruleVo, List<Integer> stageIds,
			List<Integer> exceptCustomerIds) throws SzException {
		String hql = getNoActivityBackHsql(companyId, ruleVo, stageIds);
		if (null != exceptCustomerIds && !exceptCustomerIds.isEmpty()) {
			hql += " and id not in (" + SysUtils.combineList(exceptCustomerIds, ",") + ")";
		}
		return clearApprovedCustomers(getDao().getDaoSupport().queryObjects(hql, -1, -1));
	}

	/**
	 * 未跟进已退回公海
	 * 
	 * @param companyId
	 * @param ruleVo
	 * @param stageIds
	 * @return
	 * @throws SzException
	 */
	public List<UserCountPojo> noActivityDidBackGroupByUser(String companyId, OpenSeeRulePipelinePojo ruleVo,
			List<Integer> stageIds) throws SzException {
		String hql = getnoActivityDidBackHql(companyId, ruleVo, stageIds);
		List<CrmCustomerVO> customers = getDao().getDaoSupport().queryObjects(hql, -1, -1);
		return classifyUserCount(customers);
	}

	// 未跟进退回公海
	public List<CrmCustomerVO> noActivityDidBack(String companyId, OpenSeeRulePipelinePojo ruleVo,
			List<Integer> stageIds, List<Integer> exceptCustomerIds) throws SzException {
		String hql = getnoActivityDidBackHql(companyId, ruleVo, stageIds);
		if (null != exceptCustomerIds && !exceptCustomerIds.isEmpty()) {
			hql += " and id not in (" + SysUtils.combineList(exceptCustomerIds, ",") + ")";
		}
		return clearApprovedCustomers(getDao().getDaoSupport().queryObjects(hql, -1, -1));
	}

	// 未成单退回公海
	public List<UserCountPojo> noOrderBackGroupByUser(String companyId, OpenSeeRulePipelinePojo ruleVo,
			List<Integer> stageIds) throws SzException {
		String hql = getNoOrderBackHql(companyId, ruleVo, stageIds);
		return classifyUserCount(getDao().getDaoSupport().queryObjects(hql, -1, -1));
	}

	// 未成单退回公海
	public List<CrmCustomerVO> noOrderBack(String companyId, OpenSeeRulePipelinePojo ruleVo, List<Integer> stageIds,
			List<Integer> exceptCustomerIds) throws SzException {
		String hql = getNoOrderBackHql(companyId, ruleVo, stageIds);
		if (null != exceptCustomerIds && !exceptCustomerIds.isEmpty()) {
			hql += " and id not in (" + SysUtils.combineList(exceptCustomerIds, ",") + ")";
		}
		return clearApprovedCustomers(getDao().getDaoSupport().queryObjects(hql, -1, -1));
	}

	// 未成单已退回公海
	public List<UserCountPojo> noOrderDidBackGroupByUser(String companyId, OpenSeeRulePipelinePojo ruleVo,
			List<Integer> stageIds) throws SzException {
		String hql = getNoOrderDidBackHql(companyId, ruleVo, stageIds);
		List<CrmCustomerVO> customers = getDao().getDaoSupport().queryObjects(hql, -1, -1);

		return classifyUserCount(customers);
	}

	// 退回公海后
	public List<CrmCustomerVO> noOrderDidBack(String companyId, OpenSeeRulePipelinePojo ruleVo, List<Integer> stageIds,
			List<Integer> exceptCustomerIds) throws SzException {
		String hql = getNoOrderDidBackHql(companyId, ruleVo, stageIds);
		if (null != exceptCustomerIds && !exceptCustomerIds.isEmpty()) {
			hql += " and id not in (" + SysUtils.combineList(exceptCustomerIds, ",") + ")";
		}
		return clearApprovedCustomers(getDao().getDaoSupport().queryObjects(hql, -1, -1));
	}

	private String getNoOrderDidBackHql(String companyId, OpenSeeRulePipelinePojo ruleVo, List<Integer> stageIds) {
		String hql = "from CrmCustomerVO where isDelete=0 and lastOrderTime<=UNIX_TIMESTAMP(NOW())*1000 -("
				+ ruleVo.getNoOrderDay() + ")*86400000 and orderTime=0 and ";
		hql += "openseaId= " + ruleVo.getOpenSeaId() + " AND ownerUid != -1 and ownerUid !=0 AND companyId=" + companyId
				+ "AND ownerUid not in ( select uid from CrmOpenSeaRuleUserVO where openseaId=" + ruleVo.getOpenSeaId()
				+ ")";
		addInvalidStageId(stageIds);
		if (!stageIds.isEmpty())
			hql += " and stageId not in (" + SysUtils.combineList(stageIds, ",") + ")";
		return hql;
	}

	/**
	 * 添加无效的stageId过滤
	 * 
	 * @param stageIds
	 */
	private void addInvalidStageId(List<Integer> stageIds) {
		if (stageIds == null)
			return;
		if (!stageIds.contains(-1))
			stageIds.add(-1);
	}

	private List<CrmCustomerVO> clearApprovedCustomers(List<CrmCustomerVO> customers) throws SzException {
		if (customers.isEmpty())
			return customers;
		final List<Integer> customerIds = new ArrayList<>();
		customers.forEach(customer -> customerIds.add(customer.getId()));
		List<Integer> approvedCustomerIds = crmOrderService.approvedCustomers(customerIds);
		if (!approvedCustomerIds.isEmpty()) {
			customers = customers.stream().filter(customer -> !approvedCustomerIds.contains(customer.getId()))
					.collect(Collectors.toList());
		}
		return customers;
	}

	/**
	 * 分类按pipelineId,ownerUid,获取实际的customerid
	 * 
	 * @param customers
	 * @return
	 * @throws SzException
	 */
	private List<UserCountPojo> classifyUserCount(List<CrmCustomerVO> customers) throws SzException {
		customers = clearApprovedCustomers(customers);
		List<UserCountPojo> ret = new ArrayList<>();
		if (customers.isEmpty())
			return ret;

		Map<String, UserCountPojo> uniqueMap = new HashMap<>();
		customers.forEach(customer -> {
			String key = String.format("%d_%d", customer.getPipelineId(), customer.getOwnerUid());
			if (uniqueMap.containsKey(key)) {
				UserCountPojo pojo = uniqueMap.get(key);
				pojo.getCustomerIds().put(customer.getId(), true);
			} else {
				UserCountPojo pojo = new UserCountPojo();
				pojo.setPipelineId(customer.getPipelineId());
				pojo.setUserId(customer.getOwnerUid());
				pojo.getCustomerIds().put(customer.getId(), true);
				uniqueMap.put(key, pojo);
				ret.add(pojo);
			}
		});
		return ret;
	}

	private String getnoActivityDidBackHql(String companyId, OpenSeeRulePipelinePojo ruleVo, List<Integer> stageIds) {
		String hql = "from CrmCustomerVO where isDelete=0 and lastActiveRecordTime<=UNIX_TIMESTAMP(NOW())*1000 -("
				+ ruleVo.getNoActivityDay() + ")*86400000 and ";
		hql += "openseaId= " + ruleVo.getOpenSeaId() + " AND ownerUid != -1 and ownerUid !=0 AND companyId=" + companyId
				+ "AND ownerUid not in ( select uid from CrmOpenSeaRuleUserVO where openseaId=" + ruleVo.getOpenSeaId()
				+ ")";
		addInvalidStageId(stageIds);
		if (!stageIds.isEmpty())
			hql += " and stageId not in (" + SysUtils.combineList(stageIds, ",") + ")";
		return hql;

	}

	private String getNoOrderBackHql(String companyId, OpenSeeRulePipelinePojo ruleVo, List<Integer> stageIds) {
		String hql = "from CrmCustomerVO where isDelete=0 and lastOrderTime<=UNIX_TIMESTAMP(NOW())*1000 -("
				+ ruleVo.getNoOrderDay() + "-1)*86400000 and orderTime=0 and ";
		hql += "openseaId= " + ruleVo.getOpenSeaId() + " AND ownerUid != -1 and ownerUid !=0 AND companyId=" + companyId
				+ "AND ownerUid not in ( select uid from CrmOpenSeaRuleUserVO where openseaId=" + ruleVo.getOpenSeaId()
				+ ")";
		addInvalidStageId(stageIds);
		if (!stageIds.isEmpty())
			hql += " and stageId not in (" + SysUtils.combineList(stageIds, ",") + ")";
		return hql;
	}

	private String getNoActivityBackHsql(String companyId, OpenSeeRulePipelinePojo ruleVo, List<Integer> stageIds) {
		String hql = "from CrmCustomerVO where isDelete=0 and lastActiveRecordTime<=UNIX_TIMESTAMP(NOW())*1000 -("
				+ ruleVo.getNoActivityDay() + "-1)*86400000 and ";
		hql += "openseaId= " + ruleVo.getOpenSeaId() + " AND ownerUid != -1 and ownerUid !=0 AND companyId=" + companyId
				+ "AND ownerUid not in ( select uid from CrmOpenSeaRuleUserVO where openseaId=" + ruleVo.getOpenSeaId()
				+ ")";
		if (!stageIds.isEmpty())
			hql += " and stageId not in (" + SysUtils.combineList(stageIds, ",") + ")";
		return hql;
	}
}
